package org.dbrd.detector.tfidf;

import java.io.Serializable;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class TFCollection implements Serializable {

	private static class Frequency {

		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;

		private int frequency;

		public Frequency(final int frequency) {
			this.frequency = frequency;
		}

		public Frequency copy() {
			return new Frequency(this.frequency);
		}

		public void increase() {
			this.frequency++;
		}

		public int toIntValue() {
			return this.frequency;
		}
		
	}

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private final Map<String, Frequency> tf = new HashMap<String, Frequency>();

	private int termCount;
	
	/**
	 * add a term to the TFCollection. the corresponding tf will be increased by
	 * 1.
	 * 
	 * @param term
	 * @return
	 */
	public void addTerm(final String term) {
		Frequency value = this.tf.get(term);
		if (value == null) {
			value = new Frequency(1);
			this.tf.put(term, value);
		} else {
			value.increase();
		}
		this.termCount++;
	}

	public void clear() {
		this.tf.clear();
		this.termCount = 0;
	}

	public TFCollection copy() {
		final TFCollection newOne = new TFCollection();
		for (final Map.Entry<String, Frequency> entry : this.tf.entrySet()) {
			newOne.tf.put(entry.getKey(), entry.getValue().copy());
		}
		newOne.termCount = this.termCount;
		return newOne;
	}

	public int getFrequency(final String term) {
		final Frequency value = this.tf.get(term);
		if (value == null) {
			return 0;
		} else {
			return value.toIntValue();
		}
	}

	public double getProbability(final String term) {
		return this.getFrequency(term) * 1.0 / this.termCount;
	}

	public int getTermCount() {
		return this.termCount;
	}

	public String[] getTerms() {
		final Set<String> keys = this.tf.keySet();
		return keys.toArray(new String[keys.size()]);
	}

	public Set<String> getTermsSet() {
		return Collections.unmodifiableSet(this.tf.keySet());
	}

	public void unite(final TFCollection collection) {
		this.termCount += collection.termCount;
		for (Map.Entry<String, Frequency> entry: collection.tf.entrySet()) {
			if (this.tf.containsKey(entry.getKey())) {
				this.tf.get(entry.getKey()).frequency += entry.getValue().frequency;
			} else {
				this.tf.put(entry.getKey(), entry.getValue().copy());
			}
		}
	}
	
	

	

}
